package com.sharemarking.platform.controller;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.List;
import java.util.UUID;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.Cache.ValueWrapper;
import org.springframework.cache.CacheManager;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.sharemarking.platform.service.ValidateCodeService;
import com.sharemarking.system.dto.ExceptionType;
import com.sharemarking.system.entity.Role;
import com.sharemarking.system.entity.User;
import com.sharemarking.system.exception.ApiException;
import com.sharemarking.system.mapper.RoleMapper;
import com.sharemarking.system.mapper.UserMapper;
import com.sharemarking.system.service.impl.AuthenticationFailureListenerImpl;

@Controller
public class IndexController {
	
	private final String LOGIN_IMAGE_VALIATECODE="LOGIN_IMAGE_VALIDATECODE";
	private final String REGISTER_IMAGE_VALIDATECODE="REGISTER_IMAGE_VALIDATECODE";
	private final String REGISTER_SMS_VALIDATECODE="REGISTER_SMS_VALIDATECODE";
	
	@Autowired
	private UserMapper um;
	
	@Autowired
	private RoleMapper rm;
	
//	@Autowired
//	private KafkaService ks;
	
	@Autowired
	PasswordEncoder pe;
//	
//	@Autowired
//	KafkaProperties kp;
	
	@Autowired
	private ValidateCodeService vcs;
	
	@Autowired
	private CacheManager cm;
	
	@GetMapping({"","index"})
	public String index(){
		return "index";
	}
	
	
	
	
	
	@GetMapping("login")
	public void login(HttpServletRequest req,Model model){
		
		String xRealIp=req.getHeader("X-real-ip");
		boolean needValidate=false;
		boolean denied=false;
		if(xRealIp!=null) {
			Cache c=cm.getCache(AuthenticationFailureListenerImpl.remoteLoginFailureTimesCacheName);
			ValueWrapper vw=c.get(xRealIp);
			Integer count=vw==null?0:(Integer)vw.get();
			needValidate=count>3;
			denied=count>10;
		}
		model.addAttribute("needValidate", needValidate);
		model.addAttribute("denied", denied);
		model.addAttribute("reqId", UUID.randomUUID().toString());
		model.addAttribute("ts", System.currentTimeMillis());
	}
	
	@GetMapping("loginValidateCode/{reqId}")
	public void loginValidateCode(HttpServletResponse response,@PathVariable("reqId") String reqId) throws IOException{
		Object[] validateCode=vcs.createImage();
		Cache cache=cm.getCache(LOGIN_IMAGE_VALIATECODE);
		cache.put(reqId, validateCode[0]);
		response.setContentType("image/png");
		ImageIO.write((BufferedImage)validateCode[1], "png", response.getOutputStream());
		response.getOutputStream().flush();
	}
	
	@GetMapping("register")
	public void register(Model model) {
		String rand=UUID.randomUUID().toString();
		model.addAttribute("reqId", rand);
		model.addAttribute("ts", System.currentTimeMillis());
		model.addAttribute("user", new User());
	}
	
	@PostMapping("register")
	@Transactional
	public String register(User user,String reqId,String validateCode,Model model){
		List<Role> roleList=rm.getAll();
		int roleId=0;
		for(Role role: roleList){
			if(role.getName().equals("企业用户"))roleId=role.getId();
		}
		if(roleId==0)return "error/null";
		ValueWrapper vw=cm.getCache(REGISTER_SMS_VALIDATECODE).get(user.getMobile());
		if(vw==null || !validateCode.equals(vw.get())) {
			cm.getCache(REGISTER_SMS_VALIDATECODE).evict(user.getMobile());
			String rand=UUID.randomUUID().toString();
			model.addAttribute("reqId", rand);
			model.addAttribute("ts", System.currentTimeMillis());
			model.addAttribute("errMsg", "无效短信验证码");
			model.addAttribute("user", user);
			return "register";
		}
		
		user.setEnabled(Boolean.TRUE);
		user.setName("");
		user.setEmail("");
		user.setPassword(pe.encode(user.getPassword()));
		um.insert(user);
		um.insertUserRole(user.getId(), roleId);
		return "redirect:/";
	}
	
	/**
	 * 检验登录名是否存在
	 * @param param
	 * @return
	 */
	@GetMapping("checkUsername")
	@ResponseBody
	public void checkUsername(String username){
		User u=um.getByLoginName(username);
		if(u!=null)throw new ApiException(ExceptionType.DUPLICATE_USERNAME);
	}
	
	/**
	 * 检验手机号是否存在
	 * @param param
	 * @return
	 */
	@GetMapping("checkMobile")
	@ResponseBody
	public void checkMobile(String mobile){
		User u=um.getByMobile(mobile);
		if(u!=null)throw new ApiException(ExceptionType.DUPLICATE_MOBILE);
	}
	
	@GetMapping("registerValidateCode/{reqId}")
	public void registerValidateCode(HttpServletResponse response,@PathVariable("reqId")String reqId) throws IOException{
		Object[] validateCode=vcs.createImage();
		Cache cache=cm.getCache(REGISTER_IMAGE_VALIDATECODE);
		cache.put(reqId, validateCode[0]);
		response.setContentType("image/png");
		ImageIO.write((BufferedImage)validateCode[1], "png", response.getOutputStream());
		response.getOutputStream().flush();
	}
	
//	@PostMapping("smsCode/{reqId}")
//	@ResponseBody
//	public Map<String,Object> smsCode(String validateCode,String mobile,@PathVariable("reqId")String reqId) {
//		Cache cache=cm.getCache(REGISTER_IMAGE_VALIDATECODE);
//		ValueWrapper vw=cache.get(reqId);
//		String registerValidateCode=vw==null?null:(String)vw.get();
//		Map<String,Object> map=new HashMap<String,Object>(2);
//		if(validateCode==null||!validateCode.equalsIgnoreCase(registerValidateCode)) {
//			map.put("success", 0);
//			map.put("msg", "图形验证码错误");
//			return map;
//		}else {
//			ValueWrapper v=cm.getCache(REGISTER_SMS_VALIDATECODE).get(mobile);
//			if(v!=null) {
//				map.put("success", 0);
//				map.put("msg", "请勿重复发送短信");
//				return map;
//			}
//			map.put("success", 1);
//			map.put("msg", "短信已发送");
//			int rand=new Random().nextInt(1000000);
//			String code=String.format("%06d", rand);
//			cm.getCache(REGISTER_SMS_VALIDATECODE).put(mobile,code);
//			Messeage mes=new Messeage(MesseageType.REGISTER, mobile, "{\"code\":\""+code+"\"}");
//			ks.publishAvroObj(kp.getTopic().getSendMesseage(), mes);
//			return map;
//		}
//	}
	
}
